<?php
class XINHUA
{
	static public $mysqlser = array();
	static public $rediser  = array();
	static public $mongser  = array();
	static public $memser   = array();
	static public $memType  = '';
	static public $token;
	static public $userid 	= '';
	static public $callbackData = array(
									0	=> '成功',
									-1	=> '未知异常',
									-2	=> '无效参数',
									-3	=> '未登录',
									-4	=> '无权访问',
									-5	=> '用户名不存在',
									-6	=> '密码错误',
									-7	=> '用户已存在',
									-8	=> '用户不存在',
									-9	=> '校验失败',
									-10	=> '有严禁词'
									);
	static public $header 	= array(
								'useragent' => 1 ,
								'channelid'	=> 1 ,
								'productid'	=> 1 ,
								'userid'	=> 0 ,
								'uniqueid'	=> 1 ,
								'usertoken' => 0 ,
								);
	// 路由控制
	static public function START()
	{
		$rout  = __SYS_DEFAULT_CONTROLLER__ ; //index
		if(isset($_GET[__SYS_ROUT__]) && !empty($_GET[__SYS_ROUT__])) //r
		{
			$tmp = preg_match('/^[a-z]+(\/[a-z]+)*$/',$_GET[__SYS_ROUT__]);
			if(!$tmp)
			{
				self::page404();
			}
			$rout = $_GET[__SYS_ROUT__]; //? nginx如何变成r的
		}
		$root = __SYS_APP_PATH__.$rout . '.php' ; // /home/xuanwen/sites/api.xw.feedss/application/
		if(!file_exists($root))
		{
			self::page404();
		}
		header('Content-Type:text/html;charset='.__SYS_CHARSET__.'');
		include($root);
	}
	static public function page404()
	{
		@header("http/1.1 404 not found"); 
		@header("status: 404 not found");
		if(__SYS_PAGE404__ != '')
		{
			include(__SYS_PAGE404__);
		}
		exit;
	}
	
	// 验证验证头
	static public function checkHead( $typeid = 0 )
	{
		self::head();
		self::log();
		if( isset($_SERVER['HEAD']) && !empty($_SERVER['HEAD']))
		{
			foreach(self::$header as $k=>$v)
			{
				$type =  $v ? $v :$typeid;
				if(isset($_SERVER['HEAD'][$k]))
				{
					if($type)
					{
						if(empty($_SERVER['HEAD'][$k]))
						{
							self::callback(-4,'',array('tips'=>'头部'.$k.'参数数值为空'));
						}
					}
				}else{
					if($v==1)
					{
						self::callback(-4,'',array('tips'=>'缺少头部'.$k.'参数'));
						break;
					}	
				}
			}	
		}else{
			self::callback(-4,'',array('tips'=>'缺少头部共有参数'));
		}	
		if(!isset($_SERVER['HEAD']['userid']))
		{
			$_SERVER['HEAD']['userid'] = '';
			/*
			if($_SERVER['HEAD']['useragent'] == 'iphone')
			{
				$_SERVER['HEAD']['userid'] = @$_SERVER['HEAD']['uniqueid'];
			}
			*/
			
		}else{
			self::$userid =  $_SERVER['HEAD']['userid'];
		}
		// 认证TOKEN是否合法
		if( $typeid )
		{
			if(!isset($_SERVER['HEAD']['usertoken']) || empty($_SERVER['HEAD']['usertoken']))
			{
				self::callback(-9,'登录超时',array('tips'=>'登录校验失败0'));
			}
			self::lib('AUTH');
			$string =  unserialize( base64_decode( AUTH::decode(urldecode($_SERVER['HEAD']['usertoken'])) ) );
			if(!is_array($string))
			{
				self::callback(-9,'登录超时',array('tips'=>'登录校验失败1'));
				self::log(0,'timeout',array('token'=>$_SERVER['HEAD']['usertoken'] , 'stateCode'=>-9,'t'=>'登录超时'));
				exit;
			}
			foreach( $string as $k=>$v)
			{
				/*
				if($k != '_logintime')
				{
					if($k!= 'productid')
					{
						if($_SERVER['HEAD'][$k] !=$v)
						{
							self::callback(-9,$k.'校验失败',array('tips'=>$k.'登录校验失败2'));exit;
							self::log(0,'timeout',array('token'=>$_SERVER['HEAD']['usertoken'] , 'stateCode'=>-9,'t'=>$k.'校验失败'));
							break;
						}
					}
				}
				*/
				
				if ($k != '_logintime' && $k != 'productid' && $k != 'channelid')
				{
						if($_SERVER['HEAD'][$k] !=$v)
						{
							self::callback(-9,$k.'校验失败',array('tips'=>$k.'登录校验失败2'));exit;
							self::log(0,'timeout',array('token'=>$_SERVER['HEAD']['usertoken'] , 'stateCode'=>-9,'t'=>$k.'校验失败'));
							break;
						}					
				}
				
			}
			if( __SYS_USER_SSO__ )
			{
				if(!$string['_logintime']) self::callback(301,'已经在其他地方登录，请重新登录',array('tips'=>''));
				$logintime = self::redis('r')->get(__SYS_CACHE_FIX__ . 'user_sso_'.$string['userid']);
				if($string['_logintime'] != $logintime )
				{
					self::callback(301,'已经在其他地方登录，请重新登录',array('tips'=>''));
				}
			}
			self::$token = $string;
			self::$userid =  self::$token['userid'];
		}
	}

	// 返回信息
	static public function callback( $code = -4 , $msg = '' ,  $data = array() , $ext = array() )
	{
		$msgstring = $msg;
		if(!$msg)
		{
			if(array_key_exists($code, self::$callbackData))
			{
				$msgstring =  self::$callbackData[$code];
			}
		}
		$callback = array(
						'code' => (int)$code ,
						'msg'  => $msgstring ,
						'data' => $data ,
						);
		//UPDATE
		if(!empty($ext) && is_array($ext))
		{
			foreach($ext as $k=>$v)
			{
				if(!array_key_exists($k, $callback))
				{
					$callback[$k]	= $v;
				}
			}
		}
		exit(json_encode($callback));
	}
	// 返回信息
	static public function syscallback( $code = -4 , $msg = '' ,  $data = array() )
	{
		$msgstring = $msg;
		if(!$msg)
		{
			if(array_key_exists($code, self::$callbackData))
			{
				$msgstring =  self::$callbackData[$code];
			}
		}
		$callback = array(
						'code' => (int)$code ,
						'msg'  => $msgstring ,
						);
		//UPDATE
		if(!empty($data) && is_array($data))
		{
			foreach($data as $k=>$v)
			{
				if(!array_key_exists($k, $callback))
				{
					$callback[$k]	= $v;
				}
			}
		}
		else
		{
			$callback['data'] = array();
		}
		exit(json_encode($callback));
	}

	// 引入类
	static public function lib($k,$new = false)
	{
		$root = __SYS_LIB_PATH__ . $k . '.class.php';
		if( file_exists( $root ) )
		{
			include_once($root);
			if($new)
			{
				return new $k();
			}
		}else{
			exit('PHPERROR:Can\'t Find '.$root.'');
		}
	}
	// 引用应用类
	static public function app($k,$new = false)
	{
		$root = __SYS_APP_PATH__ . $k . '.class.php';
		if( file_exists( $root ) )
		{
			include_once($root);
			if($new)
			{
				return new $k();
			}
		}else{
			exit('PHPERROR:Can\'t Find '.$root.'');
		}
	}
	// 返回HEAD
	static public function head()
	{
		$headers = array();
		if( $_SERVER )
		{
			foreach ($_SERVER as $key => $value) 
			{ 
		    	if ('HTTP_' == substr($key, 0, 5)) 
		    	{ 
		        	$headers[strtolower(substr($key, 5))] = $value; 
		    	} 
			}
		} 
		$_SERVER['HEAD'] = array();
		if(!empty($headers))
		{
			$_SERVER['HEAD'] = $headers ;//array_change_key_case($headers) ;
		}
		return $_SERVER['HEAD'];
	}
	// 返回REDIS对象
	static public function redis($dbtype = 'r' , $objtype = 'default' )
	{
		$key = $objtype . '_' . $dbtype;
		if( !isset(self::$rediser[$key]))
		{
			self::_redisConnect( $key , $dbtype ,  $objtype );
		}
		return self::$rediser[$key];
	}
	static private function _redisConnect( $key = '', $dbtype = 'r' , $objtype = 'default' )
	{
		$DB_configs = $_SERVER[__SYS_GLOBAL_SERVER__]['comp']['redis'][$objtype][$dbtype];
		krsort( $DB_configs );
		$obj = null;
		try{
			 $obj = new Redis();
		}catch(Exception $e ) {
			throw new Exception( $e->getMessage() );
		}
		if( array_key_exists('host', $DB_configs ) )
		{
			$DB_configss[0] = $DB_configs ;  
		}else{
			$DB_configss = $DB_configs;
		}

		if( is_object( $obj ) ){
			foreach($DB_configss as $k=>$v)
			{
				$d = $obj->connect($v['host'], $v['port'] ,(int)@$v['timeout']);
				if( $d )
				{
					$obj->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
					break;
				}
			}
			self::$rediser[$key]  = $obj;
		}else{
			if( !class_exists('redisObj'))
			{
				eval('class redisObj{ function __construct(){} function __call($k,$p){ return array();} }');
			}
			
			self::$rediser[$key] = new redisObj();
		}	

	}
	// 返回MYSQL对象
	static public function mysql( $dbtype = 'r' , $objtype = 'default' )
	{
		$key = $objtype . '_' . $dbtype;
		if( !isset(self::$mysqlser[$key]) )
		{
			self::_mysqlConnect( $key, $dbtype  , $objtype  );
		}
		return self::$mysqlser[$key];
	}

	static private function _mysqlConnect( $key = '', $dbtype = 'r' , $objtype = 'default' )
	{
		/*
		$DB_config = $_SERVER[__SYS_GLOBAL_SERVER__]['comp']['mysql'][$objtype];
		$dsn = "mysql:dbname=".$DB_config[$dbtype]['name'].";host=".$DB_config[$dbtype]['host'].";port=".$DB_config[$dbtype]['port']."" ;
			$option = array(
						PDO::ATTR_EMULATE_PREPARES   => true,
						PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES '".$DB_config[$dbtype]['charset']."'",
			);
			try {
				self::$mysqlser[$key] = new PDO($dsn, $DB_config[$dbtype]['user'], $DB_config[$dbtype]['password'], $option);
			} catch(Exception $e ) {
				throw new Exception( $e->getMessage() );
			}
		*/
		
		$DB_config = $_SERVER[__SYS_GLOBAL_SERVER__]['comp']['mysql'][$objtype][$dbtype];	
		krsort($DB_config);
		if(array_key_exists('host', $DB_config))
		{
			$DB_configs[] =  $DB_config ;
		}else{
			$DB_configs   = $DB_config ;
		}
		$obj = null ;
		foreach( $DB_configs as $k=>$v)
		{
			$option = array(
						PDO::ATTR_EMULATE_PREPARES   => true,
						PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES '".$v['charset']."'",
			);
			$dsn = "mysql:dbname=".$v['name'].";host=".$v['host'].";port=".$v['port']."" ;
			try {
				$tmpObj =  @new PDO($dsn, $v['user'], $v['password'], $option);
			}catch(Exception $e ) {
				$tmpObj = null;
			}
			if($tmpObj)
			{
				$obj = $tmpObj;
				unset($tmpObj);
				break;
			}
		}
		if(!$obj)
		{
			exit(json_encode(array('code'=>500,'msg'=>'DB Faild','data'=>array('_'=>time()))));
		}
		self::$mysqlser[$key] = $obj;
		
	}

	// 获取MEMCACHED

	static public function memcached( $dbtype = 'r' , $objtype = 'default')
	{
		$key = $objtype . '_' . $dbtype;
		if( !isset(self::$memser[$key]) )
		{
			self::_memConnect( $key, $dbtype  , $objtype  );
		}
		return self::$memser[$key];
	}

	static private function _memstart()
	{
		if ( ! extension_loaded('memcached') && !extension_loaded('memcache'))exit('PHPexsion:memcached!');
		if(extension_loaded('memcached'))
		{

			$obj = new Memcached();
			$obj->setOption(Memcached::OPT_SERIALIZER, Memcached::SERIALIZER_PHP);
			$obj->setOption(Memcached::OPT_HASH, Memcached::HASH_DEFAULT);
			$obj->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);	
			$obj->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
			return $obj;
		}else{
			self::$memType = 'memcache';
			if(!self::$memType)
			{
				@ini_set('memcache.hash_function','crc32');
				@ini_set('memcache.hash_strategy','consistent');
			}
			$obj =  new Memcache();
		}
		return $obj;
	}

	static private function _memConnect( $key, $dbtype  , $objtype  )
	{
		$obj=self::_memstart();
		$config = $_SERVER[__SYS_GLOBAL_SERVER__]['comp']['memcached'][$objtype][$dbtype];
		if(!self::$memType)
		{
			$obj->addServers( $config );

		}else{
			foreach($config as $v)
			{
				$obj->addServer($v[0], $v[1]);
			}
		}
		self::$memser[$key] = $obj;
	}

	// 获取MONGODB

	static public function mongodb( $dbtype = 'r' , $objtype = 'default' )
	{
		$key =  $objtype . '_' . $dbtype;
		if( !isset(self::$mongser[$key]) )
		{
			self::_mongoConnect( $key, $dbtype  , $objtype  );
		}
		return self::$mongser[$key];
	}

	static private function _mongoConnect( $key, $dbtype  , $objtype )
	{
		$m 		= new MongoClient($_SERVER[__SYS_GLOBAL_SERVER__]['comp']['mongodb'][$objtype][$dbtype]['dsn']);
		$dbname = $_SERVER[__SYS_GLOBAL_SERVER__]['comp']['mongodb'][$objtype][$dbtype]['db'];
		self::$mongser[$key] = $m->$dbname;
	}
	// 全球唯一ID
	static public function uuid()
	{
		$data = self::mysql('r')->query("SELECT uuid() AS id ")->fetch(PDO::FETCH_ASSOC);
		return str_replace('-', '', $data['id']);
	}

	// 获取全局评论设置
	static public function getGlobalComment($type = 1,$newsid=0)
	{
		// 获取全局是否可评论
		if($type == 1 )
		{
			$key = __SYS_CACHE_FIX__ . 'comment_setting';
			//$data = self::redis('r')->get($key);
			$data = self::memcached('r')->get($key);
			if($data)
			{
				$data = unserialize($data);
				return $data['iscomment'];
			}else{
				$sql = "SELECT `setting` FROM `module` WHERE `module`='admin' AND `name`='admin' ";
				$tmp = self::mysql('r','cms')->query($sql)->fetch(PDO::FETCH_ASSOC);
				$iscomment = 0;
				if($tmp)
				{
					eval("\$tmpdata=".$tmp['setting'].";");
					$iscomment = (int)@$tmpdata['iscomment'];
					$tmpdata['iscomment'] = $iscomment;
				}else{
					$tmpdata['iscomment'] = 0;
				}
				//self::redis('w')->setex($key , 300 , $tmpdata );
				self::memcached('r')->set($key, serialize($tmpdata), 300);
				return $iscomment;
			}
		}else{
			$key = __SYS_CACHE_FIX__ . 'comment1_setting_'.$newsid;
			//$data = self::redis('r')->get($key);
			$data = self::memcached('r')->get($key);
			if($data==false){
				$sql = "SELECT iscomment FROM `xuanwen` WHERE id={$newsid} LIMIT 1";
				$xuanwenData =  self::mysql('r','cms')->query($sql)->fetch(PDO::FETCH_ASSOC);
				$d = 0 ;
				if($xuanwenData)
				{
					$d = (int)$xuanwenData['iscomment'];
				}
				//self::redis('w')->setex($key , 60 , $d );
				self::memcached('r')->set($key, $d, 60);
				return $d;
			}else{
				return (int)$data;
			}

		}
	}

	// 获取用户昵称LOGO
	static public function getUserInfo( $userid ,$model = '' )
	{
		if(!$userid) {
			$userinfo =  array('logo'=>'' , 'nickname'=>'');
			return $userinfo;
		}
		$key 		= __CACHE_USER_INFO__.$userid;
		//$userinfo 	= self::redis('w')->get( $key );
		$userinfo = self::memcached('r')->get($key);
		if( empty( $userinfo ) )
		{
			$sql ="SELECT * FROM `user` WHERE `userId`='".$userid."' LIMIT 1"; 
			$rs = self::mysql('w')->query($sql)->fetch(PDO::FETCH_ASSOC);
			$logo = ($rs['logo'] ? preg_match('/^http(.*)/i',$rs['logo']) ? $rs['logo'] :  __SYS_UPLOAD_URL__.$rs['logo'] : '');
			$userinfo =  array('logo'=>$logo,'nickname'=>$rs['nickname']);
			//self::redis('w')->set(__CACHE_USER_INFO__.$userid, $userinfo);
			$userinfo = serialize($userinfo);
			self::memcached('r')->set($key, $userinfo, 600);			
		}
		$userinfo = unserialize($userinfo);
		if( $model == '')
		{
			return $userinfo;
		}
		return $userinfo[$model];
	}

	// 创建log目录
	static public function log( $type = 0 , $logdir = null , $res=array())
	{
		//APP请求日志
		if(!is_array($type) && $type == 0 )
		{
			$tmpstr  = 'Request-Time:';
			$tmpstr  .= date('Y-m-d H:i:s')."\n";
			$tmpstr  .= 'Request-Address:/';
			$tmpstr  .= @$_GET[__SYS_ROUT__]."\n";
			$tmpstr  .= 'Request-Header:';
			$tmpstr  .= var_export(@$_SERVER['HEAD'],true)."\n";
			$tmpstr  .= 'Request-params:';
			$tmpstr  .= var_export(@$_REQUEST,true)."\n";
			$name 	 =  !$logdir ? '' :  $logdir ;
			if(!empty($res))
			{
				$tmpstr  .= "Respones:\n";
				$tmpstr  .= var_export(@$res,true)."\n";
			}
			$tmpstr  .= "====================\n";
			@error_log($tmpstr,3 ,__SYS_LOGDIR__.$name.date('Y-m-d').'.log');
		}
	}
}

